/**
 *       Copyright (c) 2012 Lukas Zaruba
 *
 *   This file is part of Robot Playground.
 *
 *   Robot Playground is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   Robot Playground is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with Robot Playground. If not, see <http://www.gnu.org/licenses/>.
 */
package net.zarubsys.commons.log4j.internal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map.Entry;
import java.util.Properties;

import net.zarubsys.commons.log4j.cfg.Log4JConfigProvider;
import net.zarubsys.commons.log4j.cfg.WorkspaceConfigProvider;
import net.zarubsys.commons.log4j.listener.EclipseLogListener;

import org.apache.log4j.PropertyConfigurator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;


/**
 * Based on loggin facility from Media Solutions Slovakia, a.s.
 * @author Lukas Zaruba, lukas.zaruba@gmail.com
 */
public class Activator extends Plugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "net.zarubsys.commons.log4j";

	// The shared instance
	private static Activator plugin;

	/**
	 * The constructor
	 */
	public Activator() {
	}

	@Override
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		Properties properties = new Properties();
		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint("net.zarubsys.commons.log4j.configurations");
		IExtension[] extensions = extensionPoint.getExtensions();
		for (IExtension ext : extensions) {
			IConfigurationElement[] cfgElems = ext.getConfigurationElements();
			for (IConfigurationElement cfg : cfgElems) {
				String name = cfg.getName();	
				/*
				 * Loads configuration from resource based
				 * configuration called properties.
				 */
				if (name.equals("properties")) {
					Bundle bundle = Platform.getBundle(cfg.getNamespaceIdentifier());
					String path = cfg.getAttribute("resource");
					System.out.println("Loading Log4j properties file from bundle '" + bundle.getSymbolicName() + "' path '" + path + "'...");
					properties.putAll(readResource(path, bundle));
					
				/*
				 * Loads configuration from class based contribution
				 */
				} else if (name.equals("propertiesProviders")) {
					Log4JConfigProvider provider;
					try {
						provider = (Log4JConfigProvider) cfg.createExecutableExtension("class");
					} catch (CoreException e) {
						System.err.println("Cannot create executable extension from contribution " +
								"from bundle " + cfg.getContributor().getName() + ". Skipping it.");
						continue;
					}
					System.out.println("Loading Log4j properties from provider '" + provider.getClass().getName() + "'...");
					properties.putAll(provider.getProperties());
				} else {
					System.err.println("Uknown extension name " + name + ". Skipping it.");
					continue;
				}
			}
		}
		
		PropertyConfigurator.configure(properties);
		Platform.addLogListener(new EclipseLogListener());
	}
	
	private Properties readResource(String path, Bundle bundle) {
		Properties properties = new Properties();
		URL url = bundle.getEntry(path);
		if (url == null) {
			System.err.println("Log4J configuration not found: " + 
					bundle.getSymbolicName() + ":" + path);
			return properties;
		}
		Properties props = new Properties();
		try (InputStream is = url.openStream()) {
			props.load(is);
			for (Entry<Object, Object> entry : props.entrySet()) {
				String value = entry.getValue().toString();
				entry.setValue(value.replaceAll(WorkspaceConfigProvider.PATTERN, Platform.getInstanceLocation().getURL().getFile()));
				properties.put(entry.getKey(), entry.getValue());
			}
		} catch (IOException e) {
			System.err.println("Cannot read properties from '" + url + "'. Stacktrace follows...");
			e.printStackTrace();
		}
		return properties;
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	public static Activator getDefault() {
		return plugin;
	}
	
}
